package net.wexoo.onlinedivelog.view.panels.user;

import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

import net.wexoo.onlinedivelog.entity.person.PersonBean;
import net.wexoo.onlinedivelog.proxy.person.IPersonProxy;
import net.wexoo.onlinedivelog.reusable.modalwindow.WEXModalWindow;
import net.wexoo.onlinedivelog.reusable.page.WEXWebPage;
import net.wexoo.onlinedivelog.view.pages.content.dive.DiveOverview;
import net.wexoo.onlinedivelog.view.pages.detail.user.UserDetailPage;
import net.wexoo.onlinedivelog.view.util.DiveLogSession;
import net.wexoo.onlinedivelog.view.util.NotificationPanel;

import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.AjaxLink;
import org.apache.wicket.ajax.markup.html.form.AjaxSubmitLink;
import org.apache.wicket.markup.html.form.DropDownChoice;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.FormComponent;
import org.apache.wicket.markup.html.form.IChoiceRenderer;
import org.apache.wicket.markup.html.form.PasswordTextField;
import org.apache.wicket.markup.html.form.TextField;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.CompoundPropertyModel;
import org.apache.wicket.model.PropertyModel;
import org.apache.wicket.spring.injection.annot.SpringBean;
import org.apache.wicket.util.visit.IVisit;
import org.apache.wicket.util.visit.IVisitor;

public class LoginPanel extends Panel {
  private static final long serialVersionUID = 1L;

  Form<LoginPanel> loginForm;
  private WEXModalWindow<PersonBean> registerWindow;
  private final NotificationPanel mainNotificationPanel;

  private String login;
  private String password;
  private PersonBean personBean;

  @SpringBean
  private IPersonProxy personProxy;

  public LoginPanel(String id, NotificationPanel mainNotificationPanel) {
    super(id);

    this.mainNotificationPanel = mainNotificationPanel;

    // parent component
    loginForm = new Form<LoginPanel>("f", new CompoundPropertyModel<LoginPanel>(this));
    add(loginForm);

    buildLoginButton();

    buildLoginFields();

    buildRegisterWindow();

    buildRegisterButton();

    buildLocaleChoice();
  }

  private void buildLoginFields() {
    loginForm.add(new TextField<String>("login").setOutputMarkupId(true));
    loginForm.add(new PasswordTextField("password").setOutputMarkupId(true));
  }

  private void buildLoginButton() {
    AjaxSubmitLink loginButton = new AjaxSubmitLink("loginButton") {

      private static final long serialVersionUID = 1L;

      @Override
      protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
        PersonBean loggedInPerson = personProxy.login(login, password);
        if (loggedInPerson != null) {
          ((DiveLogSession) getSession()).setLoggedInPerson(loggedInPerson);
          setResponsePage(DiveOverview.class);
        } else {
          error(getString("wrongLoginMessage"));
          mainNotificationPanel.refresh(target);
        }
      }

      @Override
      protected void onError(AjaxRequestTarget target, Form<?> form) {
        mainNotificationPanel.refresh(target);
      }
    };
    loginForm.add(loginButton);
  }

  private void buildRegisterWindow() {
    registerWindow = new WEXModalWindow<PersonBean>("registerWindow"){

      private static final long serialVersionUID = 1L;

      @Override
      protected WEXWebPage returnPageToBeCreated(PersonBean bean) {
        if(bean == null)
          bean = new PersonBean();
        personBean = bean;
        return new UserDetailPage(bean);
      }

      @Override
      protected void onCloseAction(AjaxRequestTarget target) {
        if (personBean.getLogin() != null && !personBean.getLogin().equals("")) {
          login = personBean.getLogin();
          refreshFormComponents(target);
        }
      }
    };
    loginForm.add(registerWindow);
  }

  private void buildRegisterButton() {
    AjaxLink<Void> register = new AjaxLink<Void>("registerButton") {

      private static final long serialVersionUID = 1L;

      @Override
      public void onClick(AjaxRequestTarget target) {
        registerWindow.show(target);
      }
    };
    loginForm.add(register);
  }

  private void buildLocaleChoice() {

    List<Locale> supportedLocales = new ArrayList<Locale>();
    supportedLocales.add(Locale.ENGLISH);
    supportedLocales.add(Locale.GERMAN);

    IChoiceRenderer<Locale> choiceRenderer = new IChoiceRenderer<Locale>() {

      private static final long serialVersionUID = 1L;

      @Override
      public String getIdValue(Locale locale, int index) {
        return Integer.toString(index);
      }

      @Override
      public Object getDisplayValue(Locale locale) {
        return locale.getDisplayName(locale);
      }
    };

    DropDownChoice<Locale> localeChoice = new DropDownChoice<Locale>("localeChoice", new PropertyModel<Locale>(
        getSession(), "locale"), supportedLocales, choiceRenderer) {

      private static final long serialVersionUID = 1L;

      @Override
      protected boolean wantOnSelectionChangedNotifications() {
        return true;
      }

      @Override
      protected void onSelectionChanged(Locale newSelection) {
      }
    };
    loginForm.add(localeChoice);
  }

  private void refreshFormComponents(final AjaxRequestTarget target) {
    loginForm.visitFormComponents(new IVisitor<FormComponent<?>, Void>() {

      @Override
      public void component(FormComponent<?> component, IVisit<Void> visit) {
        target.add(component);
        visit.dontGoDeeper();
      }
    });
  }

}